moddbfandomcom-20200213-history
SDL:Tutorials:Displaying a Bitmap from a Custom Resource File using SDL RWops
So, your images are safe and sound in your custom resource file, (I assume you've read the tutorial on Custom Resource Files!) now what? SDL_RWops! Gesundheit! No, I didn't just sneeze; SDL_RWops is a little-known SDL structure which allows us to load images and sounds in a very flexible manner. Instead of loading images using the standard SDL_LoadBMP function, we'll be using SDL_LoadBMP_RW, which accepts an SDL_RWops structure as a parameter. Observe: SDL_Surface *LoadBitmap(char *resourcefilename, char *bitmapfilename) { //Get the bitmap's buffer and size from the resource file int filesize = 0; char *buffer = GetBufferFromResource(resourcefilename, bitmapfilename, &filesize); //Load the buffer into a surface using RWops SDL_RWops *rw = SDL_RWFromMem(buffer, filesize); SDL_Surface *temp = SDL_LoadBMP_RW(rw, 1); //Release the bitmap buffer memory free(buffer); //Were we able to load the bitmap? if (temp NULL) { printf("Unable to load bitmap: %s\n", SDL_GetError()); exit(1); } //Convert the image to optimal display format SDL_Surface *image; image = SDL_DisplayFormat(temp); //Free the temporary surface SDL_FreeSurface(temp); //Return our loaded image return image; } This LoadBitmap routine uses SDL_RWops to load a bitmap from memory. The GetBufferFromResource function does some magic (explained below) and extracts a given bitmap from the specified custom resource file. The buffer returned by GetBufferFromResource is passed to SDL_RWFromMem which creates for us our very own SDL_RWops structure! This SDL_RWops structure is then passed to SDL_LoadBMP_RW along with a value of 1 as the second parameter. (Passing 1 means that we'd like SDL to automatically release the resource after it has been read. Better safe than sorry!) SDL_LoadBMP_RW spits out an SDL_Surface structure, and things then progress as normal (see the basic SDL bitmap display tutorial for info on how to display the image stored within an SDL_Surface structure). So, what voodoo is performed by GetBufferFromResource? char *GetBufferFromResource(char *resourcefilename, char *resourcename, int *filesize) { //Try to open the resource file in question int fd = open(resourcefilename, O_RDONLY); if (fd < 0) { perror("Error opening resource file"); exit(1); } //Make sure we're at the beginning of the file lseek(fd, 0, SEEK_SET); //Read the first INT, which will tell us how many files are in this resource int numfiles; read(fd, &numfiles, sizeof(int)); //Get the pointers to the stored files int *filestart = (int *) malloc(sizeof(int) * numfiles); // this is probably wrong in the zip read(fd, filestart, sizeof(int) * numfiles); //Loop through the files, looking for the file in question int filenamesize; char *buffer; int i; for(i=0;i Phew! That's a whole lot of voodoo! But most of it should be familiar to you if you've read the Custom Resource Files tutorial. Basically, GetBufferFromResource loops through the various entries in our custom resource file, reading the filename strings to find one that matches the char *resourcename parameter. If it finds the file it's looking for, it loads the file data into a buffer of type char and returns it. GetBufferFromResource also modifies the data pointed to by filesize, as the size of the buffer must be known when using the SDL_RWFromMem function! These two routines are all you need to extract a bitmap from a custom resource file (assuming you've formatted your resource file as we did in the Custom Resource Files tutorial) and load it into an SDL_Surface. Source Code * Click here to download the full source code, which loads an image from a custom resource file and displays it to screen. The source code also plays a WAV sound file using SDL_mixer, so be sure to compile with an -lSDL_mixer link! Category:C Category:SDL